#include "wsteptree.h"
#include "albero.h"
#include <QVBoxLayout>
#include <QMessageBox>
#include <QMouseEvent>
#include <QAction>
#include <QMenu>

WStepTree::WStepTree(int n)
{
    //tree
    Albero a;
    a.stepTree(n);

    //widget albero
    treeView = new QTreeWidget();
    treeView->setColumnCount(1);
    QList<QTreeWidgetItem *> items;

    //creazione degli items
    items = makeTree(a.root,items);
    treeView->insertTopLevelItems(0,items);
    treeView->setHeaderHidden(true);

    //metto il filtro per gestire i tasti del mouse e della tastiera
    treeView->viewport()->installEventFilter(this);

    //connetto il menu
    treeView->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(treeView, SIGNAL(customContextMenuRequested(const QPoint &)),
            this, SLOT(showContextMenu(const QPoint &)));

    //quando si seleziona un nodo appare shift e lunghezza o torna il fattore
    //click sull'item
    connect(treeView, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(changeTreeInfo(QTreeWidgetItem*)));
    //tasto invio
    connect(treeView, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(changeTreeInfo(QTreeWidgetItem*)));

    //layout
    QVBoxLayout* layout = new QVBoxLayout();
    layout->addWidget(treeView);
    this->setLayout(layout);


}

/*pagine per i puntatori:
http://lists.trolltech.com/qt-interest/2006-06/thread00263-0.html - contextmenu
http://lists.trolltech.com/qt-interest/2008-07/msg00467.html - puntatori negli item
*/

WStepTree::WStepTree(QTreeWidgetItem *item){

    treeView = new QTreeWidget();
    treeView->setColumnCount(1);

    //Devo necessariamente fare una copia profonda degli elementi
    //NOTA IMPORTANTE:
    //la parte "DATA" degli item punta all'albero creato nella classe generante
    //quindi tutti i sottoalberi(subtree) sono dipendenti da essa, una volta eliminata
    //la classe generante vanno eliminati anche quest'ultimi
    QTreeWidgetItem* items; items = item->clone();
    treeView->insertTopLevelItem(0,items);
    treeView->setHeaderHidden(true);

    //metto il filtro per gestire i tasti del mouse e della tastiera
    treeView->viewport()->installEventFilter(this);

    //connetto il menu
    treeView->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(treeView, SIGNAL(customContextMenuRequested(const QPoint &)),
            this, SLOT(showContextMenu(const QPoint &)));

    //quando si seleziona un nodo appare shift e lunghezza o torna il fattore
    //click sull'item
    connect(treeView, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(changeTreeInfo(QTreeWidgetItem*)));
    //tasto invio
    connect(treeView, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(changeTreeInfo(QTreeWidgetItem*)));

    //layout
    QVBoxLayout* layout = new QVBoxLayout();
    layout->addWidget(treeView);
    this->setLayout(layout);

}


QList<QTreeWidgetItem*> WStepTree::makeTree(Nodo* n, QList<QTreeWidgetItem*> parent){
    QList<QTreeWidgetItem *> itemNodo, itemRes;

    Residuo* y;
    y=n->residui;

    Nodo* z;

    QTreeWidgetItem* item;
    QVariant qv;

    if(parent.isEmpty()) item = new QTreeWidgetItem((QTreeWidget*)0, QStringList(QString(tr("[%1]").arg(n->fattore.c_str()))));
    else item = new QTreeWidgetItem((parent.last()), QStringList(QString(tr("[%1]").arg(n->fattore.c_str()))));

    qv.setValue(n);
    item->setData(0,Qt::UserRole, qv);
    itemNodo.append(item);

    while (y!=NULL){
        item = new QTreeWidgetItem(itemNodo[0], QStringList(QString((n->fattore.substr(0,y->lunghezza)).c_str())));

        qv.setValue(y);
        item->setData(0,Qt::UserRole, qv);
        itemRes.append(item);

        z=y->continuazione;
        if (z!=NULL) makeTree(z,itemRes);

        y=y->succ;
    }

    /*QVariant q = item->data(0,Qt::UserRole);
    Residuo* h = q.value<Residuo*>();*/

    return itemNodo;
}

void WStepTree::changeTreeInfo(QTreeWidgetItem *item){

    //se e' stato richiamato il menu esco
    if (menu) return;

    bool convert=false; //bool controllo)

    QVariant q = item->data(0,Qt::UserRole);
    if (q.canConvert<Nodo*>()){
        convert = true; //debug
        Nodo* nodo = q.value<Nodo*>();
        //se ho visualizzato il fattore visualizzo shift e lunghezza
        if(item->text(0)==tr("[%1]").arg(nodo->fattore.c_str())){
            item->setText(0,tr("[lenght = %1, shift = %2]").arg(nodo->fattore.size()).arg(nodo->shift()));
        }
        else
            item->setText(0,tr("[%1]").arg(nodo->fattore.c_str()));
    }
    //if(!convert) QMessageBox::information(this,tr("wrong"),tr("not a Node"));
}


void WStepTree::showContextMenu(const QPoint &position){

    QList<QAction *> actions; //lista di azioni per il contextmenu

    //Action per il subtree
    QAction* action = new QAction(tr("Create SubTree"),(QObject*)0);
    //quando voglio il sottoalbero, mando il segnale
    connect(action, SIGNAL(triggered()), this, SIGNAL(subTree()));
    actions.append(action);

    //Action per le info dei nodi
    action = new QAction(tr("Show Node Info"),(QObject*)0);
    //quando voglio le info sui nodi mando il segnale
    connect(action, SIGNAL(triggered()), this, SIGNAL(nodeInfo()));
    actions.append(action);

   if (treeView->indexAt(position).isValid()) {
       QMenu::exec(actions, treeView->mapToGlobal(position));
    }
}


bool WStepTree::eventFilter(QObject *o, QEvent *e){
    //se clicco col destro voglio il menu, altrimenti cambio info
    if (e->type() == QEvent::MouseButtonPress){
        QMouseEvent *m = static_cast<QMouseEvent *>(e);
        if (m->button() == Qt::RightButton) menu = true;
        else menu=false;
        //non metto il return true, voglio che si comporti normalmente
    }
    //se premo invio voglio cambiare le info
    if (e->type() == QEvent::KeyPress) {
        QKeyEvent* k = static_cast<QKeyEvent *>(e);
        if (k->key() == Qt::Key_Enter) menu = false;
        return true;
    }

    //standard
    return QObject::eventFilter(o, e);
}
